# coding=utf-8

from bmob import *
import json
import datetime
from dateutil.relativedelta import relativedelta
import time
import datetime
import pdb

class ReadData:
    def __init__(self):
        self.b = Bmob("f5b3dbd027720a6f49c87b6a1a1c7a84", "616ee9149ae817bcd2f535b9a21050d4")

    def getYesterday(self): 
        today=datetime.date.today() 
        oneday=datetime.timedelta(days=1) 
        yesterday=today-oneday  
        return yesterday

    def getResult(self, table_name, user_id):
        lst_ret = []
        try:
            ret_str = self.b.find(
                table_name,
                BmobQuerier().addWhereEqualTo("user_id", user_id)
            ).stringData
            print(ret_str)
        except:
            print("读取%s数据失败." % (table_name))
            return lst_ret
        else:
            if not ret_str.strip() == "":
                lst_ret = json.loads(ret_str)['results']
        return lst_ret

    def getResultV2(self,table_name, user_id):
        dct = {}
        lst_all = []
        dct["user_id"] = user_id
        try:
            ret_str = self.b.find(
                table_name,
                where = dct,  # 设置查询条件, dict或BmobQuerier
                limit=500,
                order = '-createAt',
            ).stringData
            print(ret_str)
        except:
            print("读取%s数据失败." % (table_name))
            return lst_all
        else:
            if not ret_str.strip() == "":
                lst_all = json.loads(ret_str)['results']
            #pdb.set_trace()
        return lst_all

    def getResultByPage(self,table_name, user_id, page_index):
        dct = {}
        dct["user_id"] = user_id
        ret_str = self.b.find(
            table_name,
            where = dct,  # 设置查询条件, dict或BmobQuerier
            limit=100,
            skip=page_index*100
        ).stringData
        print(ret_str)
        lst_all = []
        if not ret_str.strip() == "":
            lst_all = json.loads(ret_str)['results']
        #pdb.set_trace()
        return lst_all

    def getYesterdayScore(self,table_name,user_id):
        n_score = 0
        dt_yesterday = self.getYesterday()
        max_length = 100
        page_index = 0
        data = []
        #pdb.set_trace()
        while max_length == 100:
            lst_all = self.getResultByPage(table_name, user_id, page_index)
            max_length = len(lst_all)
            page_index += 1
            data.extend(lst_all)
        #pdb.set_trace()
        for itm in data:
            str_create = itm['createdAt']
            dt_create = datetime.datetime.strptime(str_create, '%Y-%m-%d %H:%M:%S').date()
            if dt_yesterday == dt_create:
                n_score += itm['score']
                #pdb.set_trace()
        return n_score


    def getUserList(self, n_page):
        tb_name = "_User"
        ret_str = self.b.find(
            tb_name,
            where = None,  # 设置查询条件, dict或BmobQuerier
            include = None,  # 需要返回详细信息的Pointer属性，str
            limit=500,
            order = '-createAt',
            skip=n_page*500,
            keys = "objectId",  # 需要返回的属性，str
        ).stringData
        lst_user = []
        if not ret_str.strip() == "":
            lst_all = json.loads(ret_str)['results']
            #pdb.set_trace()
            for item in lst_all:
                lst_user.append(item['objectId'])
        return lst_user

    #格式：{'province_num': 169, 'city_num': 454}
    def getTrail(self, user_id):
        dict_ret = dict()
        max_length = 100
        page_index = 0
        data = []
        while max_length == 100:
            lst_all = self.getResultByPage("t_trail", user_id, page_index)
            max_length = len(lst_all)
            page_index += 1
            data.extend(lst_all)
        if not data:
            return dict_ret
        #pdb.set_trace()
        lst_provinces = []
        lst_cities = []
        for itm in data:
            if 'province' not in itm:
                continue
            if 'city' not in itm:
                continue
            province = itm["province"]
            city = itm["city"]
            if province not in lst_provinces:
                lst_provinces.append(province)
            if city not in lst_cities:
                lst_cities.append(city)
        if "热门城市" in lst_provinces:
            lst_provinces.remove("热门城市")
        lst_hot_city = ["北京市", "上海市", "天津市","重庆市"]
        for itm in lst_hot_city:
            if itm in lst_cities:
                lst_provinces.append(itm)
        dict_ret = {"province_num" : len(lst_provinces), "city_num" : len(lst_cities)}
        #pdb.set_trace()
        return dict_ret


    #格式：[0, 1, 2, 3, 4]
    def getEducation(self, user_id):
        lst_ret = []
        lst_all = self.getResult("t_education", user_id)
        if len(lst_all) == 0:
            return lst_ret
        data = lst_all
        for item in data:
            if 'eIndex' in item:
                lst_ret.append(item['eIndex'])
        #pdb.set_trace()
        return lst_ret

    def getRead(self, user_id):
        book_num = 0
        lst_all = self.getResult("t_readlist", user_id)
        if not lst_all:
            return book_num
        #lst_book = json.loads(lst_all[0]['books'])
        book_num = len(lst_all)
        #pdb.set_trace()
        return book_num

    def getSkill(self, user_id):
        skill_num = 0
        lst_all = self.getResult("t_skill", user_id)
        if not lst_all:
            return skill_num
        skill_num = len(lst_all)
        #pdb.set_trace()
        return skill_num

    def getJob(self, user_id):
        work_years = 0
        lst_all = self.getResult("t_work", user_id)
        if not lst_all:
            return work_years
        lst_job = lst_all
        lst_start_time = []
        lst_end_time = []
        if not lst_job:
            return work_years
        #pdb.set_trace()
        for expr in lst_job:
            if 'start_time' not in expr:
                continue
            if 'end_time' not in expr:
                continue
            if expr['start_time'].strip() == "":
                continue
            if expr['end_time'].strip() == "":
                continue
            lst_start_time.append(expr['start_time'])
            lst_end_time.append(expr['end_time'])
        if (len(lst_start_time) > 0) and (len(lst_end_time) > 0):
            str_start_time = min(lst_start_time)
            str_end_time = max(lst_end_time)
            work_years = 1
            try:
                dt_start = datetime.datetime.strptime(str_start_time,'%Y-%m')
                dt_end = datetime.datetime.strptime(str_end_time, '%Y-%m')
            except:
                work_years = 1
            else:
                work_years = dt_end.year - dt_start.year
        #pdb.set_trace()
        return work_years

    def getBudget(self, user_id):
        last_year_income = 0
        lst_all = self.getResult("t_property", user_id)
        #pdb.set_trace()
        if not lst_all:
            return last_year_income
        today = datetime.date.today()
        last_today = today - relativedelta(years=+1)
        for rec in lst_all:
            rec_date = datetime.datetime.strptime(rec['dateTime'],'%Y-%m').date()
            rec_income = rec['income']
            if rec_date <= today and rec_date > last_today:
                last_year_income += int(rec_income)
        return last_year_income

    def getInvest(self, user_id):
        return None

    def getBody(self, user_id):
        bmi = 0
        lst_all = self.getResult("t_health", user_id)
        if not lst_all:
            return bmi
        last_date = datetime.date(2000,1,1)
        last_bmi = 0
        for rec in lst_all:
            curr_date = datetime.datetime.strptime(rec['dateTime'],'%Y-%m-%d').date()
            #pdb.set_trace()
            weight = int(rec['weight'])
            height = rec['height'] / 100
            curr_bmi = weight / (height * height)
            if curr_date >= last_date:
                last_date = curr_date
                last_bmi = curr_bmi
        bmi = last_bmi
        return bmi

    def getHealth(self, user_id):
        return None

    def getInterst(self, user_id):
        interest_num = 0
        lst_all = self.getResult("t_interest", user_id)
        if not lst_all:
            return interest_num
        #pdb.set_trace()
        lst_interest = []
        for itm in lst_all:
            if 'interest_name' not in itm:
                continue
            if not itm['interest_name'].strip() == "":
                lst_interest.append(itm)
        interest_num = len(lst_interest)
        #pdb.set_trace()
        return interest_num
        
class CalData:
    def calTrail(self, dct):
        score = 0
        if not dct:
            return score
        province_num = dct['province_num']
        city_num = dct['city_num']
        province_num = province_num * 3
        city_num = city_num * 2
        score = province_num + city_num
        return score

    def calEducation(self, lst):
        score = 0
        if not lst:
            return score
        score_ref = [10, 30, 50, 50, 50, 100, 100, 100]
        for n in lst:
            score += score_ref[int(n)]
        return score

    def calRead(self, num):
        return num * 2

    def calSkill(self, num):
        return num * 10

    def calJob(self, num):
        return num * 10

    def calBudget(self, num):
        score = int(num / 10000) * 10
        return score

    def calInvest(self, lst):
        return 0

    def calBody(self, bmi):
        score = 0
        if bmi <= 15:
            score = 0
        elif 15.1 < bmi <= 17.4:
            score = 33
        elif 17.5 < bmi <= 18.4:
            score = 66
        elif 18.5 < bmi <= 24.9:
            score = 100
        elif 25 < bmi <= 29.9:
            score = 66
        elif 30 < bmi <= 39.9:
            score = 33
        else: # >=40
            score = 0
        return score

    def calHealth(self, lst):
        return 0

    def calInterest(self, num):
        return num * 10

class WriteData:
    def __init__(self, table_name):
        self.table_name = table_name
        self.b = Bmob("f5b3dbd027720a6f49c87b6a1a1c7a84", "616ee9149ae817bcd2f535b9a21050d4")

    def update(self,object_id, user_id, n_score, n_grow, n_biz, n_financial, n_health, n_interest):
        tb_name = "t_score"
        pt_user = BmobPointer("_User", user_id)
        total_score = n_grow + n_biz + n_financial + n_interest + n_health
        #increase_score = total_score - n_score
        increase_score = n_score
        self.b.update(
            tb_name,
            object_id,
            BmobUpdater.increment("count", 0, {
                "user_id":pt_user,
                "grow" : n_grow,
                "biz" : n_biz,
                "financial" : n_financial,
                "health" : n_health,
                "interest" : n_interest,
                "total" : total_score,
                "increase" : increase_score
            })
        )

    def insert(self, user_id, n_grow, n_biz, n_financial, n_health, n_interest):
        tb_name = "t_score"
        pt_user = BmobPointer("_User", user_id)
        self.b.insert(
            tb_name,
            BmobUpdater.increment("count", 0, {
                "user_id" : pt_user,
                "grow" : n_grow,
                "biz" : n_biz,
                "financial" : n_financial,
                "health" : n_health,
                "interest" : n_interest,
                "total" : (n_grow + n_biz + n_financial + n_interest + n_health),
                "increase":0
            })
        )
    
    def getUserScore(self, table_name, user_id):
        rec = None
        ret_str = self.b.find(
            table_name,
            BmobQuerier().addWhereEqualTo("user_id", user_id)
        ).stringData
        lst_ret = json.loads(ret_str)['results']
        if not lst_ret:
            return rec
        #pdb.set_trace()
        rec = lst_ret[0]
        return rec

if __name__ == '__main__':
    r = ReadData()
    w = WriteData("t_score")
    c = CalData()

    users = []
    page_index = 0
    curr_length = 500
    while curr_length == 500:
        lst_user = r.getUserList(page_index)
        curr_length = len(lst_user)
        #pdb.set_trace()
        page_index += 1
        users.extend(lst_user)
    #pdb.set_trace()
    
    n_index = 0
    today = datetime.date.today()
    fn = "%s.log" % today
    f = open(fn,"w")
    #users = ['7b2a5db564'] #调试完后记得注释
    print(len(users))
    for user in users:
        grow = 0
        biz = 0
        financial = 0
        health = 0
        interest = 0

        print("%d:当前用户，user_id:%s" %(n_index,user), file=f)
        print("%d:当前用户，user_id:%s" %(n_index,user))
        prgs = n_index / (len(users))
        print("当前完成进度：{:.2%}".format(prgs))

       #昨日分数 
        yesterday_score = r.getYesterdayScore('t_score_history',user)
        #pdb.set_trace()

        # 足迹
        print("足迹分数计算中......",file=f)
        print("足迹分数计算中......")
        info = r.getTrail(user)
        print(info,file=f)
        score = c.calTrail(info)
        grow += score
        
        # 教育
        print("教育分数计算中......",file=f)
        print("教育分数计算中......")
        info = r.getEducation(user)
        print(info,file=f)
        score = c.calEducation(info)
        grow += score
        
        # 阅读
        print("阅读分数计算中......",file=f)
        print("阅读分数计算中......")
        info = r.getRead(user)
        print(info,file=f)
        score = c.calRead(info)
        grow += score
        
        # 技能
        print("技能分数计算中......",file=f)
        print("技能分数计算中......")
        info = r.getSkill(user)
        print(info,file=f)
        score = c.calSkill(info)
        grow += score

        # 事业
        print("事业分数计算中......",file=f)
        print("事业分数计算中......")
        info = r.getJob(user)
        print(info,file=f)
        score = c.calJob(info)
        biz = score

        # 财富
        print("财富分数计算中......",file=f)
        print("财富分数计算中......")
        info = r.getBudget(user)
        print(info,file=f)
        score = c.calBudget(info)
        financial += score
        
        # 资产
        print("资产分数计算中......",file=f)
        print("资产分数计算中......")
        info = r.getInvest(user)
        print(info,file=f)
        score = c.calInvest(info)
        financial += score

        # 身体
        print("身体分数计算中......",file=f)
        print("身体分数计算中......")
        info = r.getBody(user)
        print(info,file=f)
        score = c.calBody(info)
        health += score
        
        # 健康
        print("健康分数计算中......",file=f)
        print("健康分数计算中......")
        info = r.getHealth(user)
        print(info,file=f)
        score = c.calHealth(info)
        health += score

        # 兴趣
        print("兴趣分数计算中......",file=f)
        print("兴趣分数计算中......")
        info = r.getInterst(user)
        print(info,file=f)
        score = c.calInterest(info)
        interest = score

        user_score = w.getUserScore("t_score", user)
        if user_score:
            score_id = user_score["objectId"]
            #old_score = user_score["total"]
            w.update(score_id, user, yesterday_score,grow, biz, financial, health, interest)
        else:
            w.insert(user, grow, biz, financial, health, interest)
        n_index += 1
        print("**************************************************",file=f)
        print("**************************************************")
        time.sleep(5)
            